Unit testing is widely accepted as a best practise when writing high quality code. Whether developing using Test Driven Delvelopment (TDD) or writing the code afterwards, the code really benefits from the process. The way the code must be structured in order to write good unit tests, really provides a "pit of success" that ensures that the code is loosely coupled and well-structured.

I recently bumped into an interesting challenge, while writing a unit test for a piece of code, that would proces some input and use the data to pass to another dependency. Essentially I wanted to test that by giving a certain input to the SUT, the dependency would be called with the expected input.

In the project in question I was using NUnit as the unit test framework and FakeItEasy as my faking framework. If you havn't tried using FakeItEasy I highly recommend it. The syntax is extremely easy to understand and can handle almost any scenario that you can think of.

FakeItEasy is handling all the dependencies injected into the SUT. Createing a fake of an interface (ie. a dependency) with FakeItEasy is - pardon the pun - easy.

_fakeBar = A.Fake<IBar>();

FakeItEasy provides an API for validating all sorts of stuff on a fake. One of the most common scenarios is checking that a method on the fake has been called. 

A.CallTo(() => _fakeBar.SomeMethod()).MustHaveHappened();

There's a lot more features in the FakeItEasy API. Take a look at the extensive documentation. It is very well written and has a lot of examples to explain the features. 

The example code below illustrates the functionality I was facing in the SUT. The class Foo is the SUT and has a dependency on a IBar interface, which has one method, SomeMethod, that takes an integer argument and returns an integer. Essentially what I wanted to test was that the value passed to the SomeMethod method was correct.

public class Foo
{
    private readonly IBar _bar;

    public Foo(IBar bar)
    {
        _bar = bar;
    }

    public int MethodToTest(int someArg)
    {
        var valueFromBar = _bar.SomeMethod(someArg + 1);
        return valueFromBar + 1;
    }
}

    public interface IBar
    {
        int SomeMethod(int someArg);
    }

In order to validate that the input to the SomeMethod method was correct I dug through the FakeItEast documentation and found the Invokes method, which has an overload that allowed me to basically take a snapshot of the argument(s) passed to a fake at the precise point in time, when the call to the fake is made.

The code below illustrates how it works. Let's go through it step by step. The test class has to private members - the SUT of type Foo and the IBar dependency. They are both set up up in the SetUp method, which is called before each test method in the class (by using the [SetUp] data annotation). This means that we have a fresh SUT before each test.

In the test method (MethodToTest_ValidInput_ValidateInputToDependency) the fake IBar (_fakeBar) is set up to return 1, when 1 is passed in. Then a variable that holds the expected value that will be passed to the SomeMethod class of the IBar is created and a variable to hold the value that is actually passed to the SomeMethod is created. Please note that the variable that will hold the actual value must have the type defined explictly when instantiated.

Next up is the interesting part. The fake is configured to save the input to the SomeMethod method in the actualInput variable, when it is instantiated with a single argument of type int. The syntax might be a little confusing at first, but it ensures that if the method you're setting up has overloads, it is possible to set up different "snapshots" to each overload. So if the SomeMethod has an overload that too a string argument it could also be handled.

After that MethodToTest on the SUT is called and expectedInputToDependency is validated to be equals to the actualInput.

[TestFixture]
public class FooTests
{
    private Foo _sut;
    private IBar _fakeBar;

    [SetUp]
    public void SetUp()
    {
        _fakeBar = A.Fake<IBar>();
        _sut = new Foo(_fakeBar);
    }

    [Test]
    public void MethodToTest_ValidInput_ValidateInputToDependency()
    {
        A.CallTo(() => _fakeBar.SomeMethod(2)).Returns(2);
        var expectedInputToDependency = 2;
        int actualInput = 0;
        A.CallTo(() => _fakeBar.SomeMethod(A<int>.Ignored)).Invokes((int i) => actualInput = i);
        var result = _sut.MethodToTest(1);;
        Assert.AreEqual(expectedInputToDependency, actualInput);
    }
}

I hope that this small blog post shed a little light over one of the many neat features that FakeItEasy has. It really helped me out when I found out how easy it was to assert the calls made to a SUT's dependency.

Comments

Be the first to post a comment

Post a comment